/* OSM layers for gvSIG. 
 * Geographic Information System of the Valencian Government
*
* Copyright (C) 2012 Nacho Brodin
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
* MA  02110-1301, USA.
* 
*/
package org.gvsig.raster.osm.downloader;

import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.gvsig.compat.net.ICancellable;
import org.gvsig.raster.cache.tile.Tile;
import org.gvsig.raster.cache.tile.exception.TileGettingException;
import org.gvsig.raster.impl.provider.tile.BaseTileDownloader;
import org.gvsig.raster.osm.io.OSMDataParameters;
import org.gvsig.raster.osm.io.OSMProvider;

/** 
 * Tile getter for Open Street Map
 * @author Nacho Brodin (nachobrodin@gmail.com)
 */
public class TileDownloaderForOSM extends BaseTileDownloader {
	private String server   = null;
	private String suffix   = null;
	
	public TileDownloaderForOSM(OSMProvider prov, 
			int tileSize) {
		super(prov, tileSize, tileSize);
		server = ((OSMDataParameters)prov.getDataParameters()).getURI();
		suffix = ((OSMDataParameters)prov.getDataParameters()).getTileSuffix();
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.gvsig.raster.cache.tile.provider.Downloader#getTile(org.gvsig.raster.cache.tile.Tile)
	 */
	public synchronized Tile downloadTile(Tile tile) throws TileGettingException {
		int level = tile.getLevel();
		int y = tile.getRow();
		int x = tile.getCol();
		String url = server + 
					(server.endsWith(File.separator) ? "" : File.separator) + 
					level + File.separator + 
					x + File.separator + 
					y + "." + suffix;
		try {
			//System.out.println("====>>>>" + url);
			downloadFile(new URL(url), tile.getFile(), tile.getCancelled());
		} catch (MalformedURLException e) {
			throw new TileGettingException(e);
		}
		readTileFromDisk(tile);
		return tile;

	}
	
	 public synchronized void downloadFile(URL url, File file, ICancellable cancel) throws TileGettingException {
	    	int IO_BUFFER_SIZE = 8 * 1024;
			int timeout =  30000;
			
			DataOutputStream dos;
			try {
				DataInputStream is;
				OutputStreamWriter os = null;
				HttpURLConnection connection = null;

				connection = (HttpURLConnection)url.openConnection();
				connection.setConnectTimeout(timeout);
				
				is = new DataInputStream(url.openStream());
				
				dos = new DataOutputStream( new BufferedOutputStream(new FileOutputStream(file)));
				byte[] buffer = new byte[IO_BUFFER_SIZE];

				int read;
				while ((read = is.read(buffer)) != -1) {
					dos.write(buffer, 0, read);
					if(cancel != null && cancel.isCanceled())
						return;
				}
				
				if(os != null) {
					os.close();
				}
				dos.close();
				is.close();
				is = null;
				dos = null;
			} catch (Exception e) {
				throw new TileGettingException(e);
			}
	    }
	
}
